"""KIEL data format
Copyright (c) 2009-2011 Christian T. Steigies <steigies@physik.uni-kiel.de>

This module offers functions to read NM data in ASCII format as used in KIEL
and return data in the format as used by NMDB."""

__author__ = "Christian T. Steigies <steigies@physik.uni-kiel.de>"
__license__ = "GPL License"

import os
import sys
import datetime
# monthrange, isleap
import calendar

# http://www.scipy.org/Tentative_NumPy_Tutorial#head-926a6c9b68b752eed8a330636c41829e6358b1d3
from numpy import * # python-numpy

from nmdb.station.station_class import station, CheckData, CheckPressure

from nmdb.tools.datetool import ParseDate, YY

kiel_station = ["kiel", "kiel2"]

## --------------------------------------------------------------------------
"""KIEL data availability
1h data since:
1957-07-01 C and O data only, no U or P data
1964-09-01 C, O, U and P data

1min data since:
1971-02-01 C, O and P data
"""
## --------------------------------------------------------------------------

class kiel(station):
    def __init__(self, station, mode, year, month):
        """read data of station for year
        if station is empty, read in all stations
        read in 1h or 1m only?
        methods to return uncorrected, corrected (+eff?) and pressure
        methods to convert to NMDB specs: count per second
        """
        
        self.mode = mode
        modes = ["1m", "1h", "1m-rt", "1h-rt", "rt", "ori", "rev"]
        if not (self.mode in modes):
            print "INVALID MODE:", self.mode
            sys.exit(1)

        station.__init__(self, station, year, month)
        self.__num = 0 # number of stations in data file
                ##self._data.append(data)                   # append dataset, still needed?

        if (self.mode == "ori" or self.mode == "1m-rt" or self.mode == "rt"):
            """real-time high resolution data, write to ori """
            #print "ori"
            self.__read_1m_rt(station, year, month)
        elif (self.mode == "rev" or self.mode == "1m"):
            """checked high resolution data, if it already exists in NMDB write to rev, new data to ori"""
            #print "rev"
            #pass # use upload_rev fo rthis
            #self.__read_1m(station, year, month)

            # testing rev algorithm with Bartol style input files:
            self.__read_file("KIEL_Minute.txt")
            
        elif (self.mode =="1h-checked"):
            """checked 1h data"""
            #print "1h"
            pass # use upload_rev for this
            #self.__read_1h(station, year)
        elif (self.mode =="1h"):
            """real-time 1h data"""
            #print "1h rt"
            self.__read_1h_rt(station, year, month)
        else:
            print "no valid mode:", self.mode
            sys.exit(1)

        

## --------------------------------------------------------------------------
    def __read_file(self, file):
        # format: yyyyy-mn-dom hh:mm:ss corr press uncorr
        #line = " "
        try:
            myfile = open(file, "r")
            line = myfile.readline() # skip the first line, which documents the file format
            while line:
                line = myfile.readline()
                if (30 < len(line) < 50): # longer line indicates description line
                    (year, month, day, hour, minute, second, dat) = ParseDate(line)
                    corr   = float(dat.split()[0])
                    press  = float(dat.split()[1])
                    uncorr = float(dat.split()[2])

                    data = [datetime.datetime(year, month, day, hour, minute, second), uncorr, press, corr]
                    #print data
                    self._c.execute('''INSERT INTO data VALUES (?, ?, ?, ?)''', data)

        except IOError:
            print "file %s not found" %(file)
            sys.exit(1)

## --------------------------------------------------------------------------
    def __read_1m_rt(self, station, year, month):
        from kiel_ascii import read_1m

        self.mode = "ori" # store datatype (ori, 1h) in object

        # hack: use nmdbrc/nmwbrc
        datapath="/home/kermes/steigies/.dosemu/drives/c/Inetpub/ftproot/CosRay!"
        #(corrected_for_pressure,corrected_for_efficiency,uncorrected,pressure) = read_1m(datapath,station,year,month)
        (dataC,dataU,dataP) = read_1m(datapath,station,year,month)

        (dummy, days) = calendar.monthrange(year,month)
        for DD in range(1,days+1):        
            for HH in range(0,24):
                for i in range(0,60):
                    print "%02i-%02i-%04i %02i:%02i %6i %6i %6i" \
                          %(DD, month, year, HH, i, dataC[DD][HH][i], dataU[DD][HH][i], dataP[DD][HH][i])
                    data = [datetime.datetime(year, month, DD, HH, i, 0), \
                            dataU[DD][HH][i], dataP[DD][HH][i], dataC[DD][HH][i]]
                    print data
                    #self._c.execute('''INSERT INTO data VALUES (?, ?, ?, ?)''', data)

## --------------------------------------------------------------------------
    def __read_1m(self, station, year, month):
        
        """read in one month of minutely data from ASCII files
        and return data in NMDB format
        TODO: if DOS uppercase of subdirectories after datapath"""

        return None
        
## --------------------------------------------------------------------------
    def __read_1h_rt(self, station, year, month):

        """read in one month of hourly data from ASCII files
        and return data in NMDB format
        TODO: if DOS uppercase of subdirectories after datapath
        TODO: fail if error in data checks"""

        from kiel_ascii import read_1h

        self.mode = "1h" # store datatype (ori, 1h) in object

        # hack: use nmdbrc/nmwbrc
        datapath="/home/kermes/steigies/.dosemu/drives/c/Inetpub/ftproot/CosRay!"
        (dataC,dataU,dataP) = read_1h(datapath,station,year,month)
        
        (dummy, days) = calendar.monthrange(year,month)
        for DD in range(1,days+1):
            for i in range(0,24):
                data = [datetime.datetime(year, month, DD, i, 0), \
                        int(dataU[DD][i]), int(dataP[DD][i]), int(dataC[DD][i])]
                print data
                #self._c.execute('''insert into data values (?, ?, ?, ?)''', data)
            
## --------------------------------------------------------------------------
    def raw(self, year=2000, month=1, day=1, hour=0, minute=0):
        """return raw values from ASCII files"""
        dt = self.dt

        return dt, corr_p, corr_e, uncorr, press

## --------------------------------------------------------------------------
    def value(self, year=2000, month=1, day=1, hour=0, minute=0, mode="processed"):
        """convert values into NMDB format:
        counts are already given as counts per second
        CheckData|Pressure with optional range
        Check* returns NULL if input == 0 or out of range"""
        
        try:
            (utc, u, p, c) = self._value(year, month, day, hour, minute)
        except TypeError:
            return None

        if mode == "raw":
            uncorr = int(u)
            p_mbar = int(p)
            corr_p = int(c)
        elif mode == "processed":
            if self.mode == "ori": # convert from cts/min to cts/sec
                uncorr = CheckData(u/60.)
                p_mbar = CheckPressure(p/10.)
                corr_p = CheckData(c/60.)
            elif self.mode == "1h":  # convert from cts/h/100 to cts/sec
                uncorr = u*100./3600.
                p_mbar = p/10.
                corr_p = c*100/3600.
            else:
                raise ValueError # illegal self.mode

        else:
            raise ValueError # illegal mode

        corr_e = corr_p
        
        return (utc, uncorr, p_mbar, corr_p, corr_e)

## --------------------------------------------------------------------------
    def print_1h(self, year, month, day, hour):
        print "%s %i %i %i %i" %(self.value(year, month, day, hour))

    def print_1m(self, year, month, day, hour, minute, mode="processed"):
        print "%s %s %s %s %s" %(self.value(year, month, day, hour, minute, mode))
                              
## --------------------------------------------------------------------------

if __name__=="__main__":
    print "This is the kiel module."

    station="kiel"
    #mode="ori"
    mode="1h"
    year=2012
    month=10
    data = kiel(station, mode, year, month)
    #__read_1m(self, station, year, month)
